import * as React from "react";
import CommonUtils from "../../utils/CommonUtils";
import PropTypes from "prop-types";

/**
 * 提示框
 * props: {
 *     content: {string|ReactComponent|HTMLElement} 内容,
 *     type: {Alert.types.*} 类型,
 *     display: {boolean} 是否显示,
 *     closable: {boolean} 可否关闭,
 *     onClose: {function} 关闭事件,
 *     survivalTime: {number} 存活时间,
 *     inClassName: {string} 显示时的样式类,
 *     outClassName: {string} 关闭时的样式类
 * }
 */
export default class Alert extends React.Component{
    /**
     * 提示类型
     * @type {{PRIMARY: string, SECONDARY: string, SUCCESS: string, DANGER: string, WARNING: string, INFO: string, LIGHT: string, DARK: string}}
     */
    static types = {
        PRIMARY: "alert-primary",
        SECONDARY: "alert-secondary",
        SUCCESS: "alert-success",
        DANGER: "alert-danger",
        WARNING: "alert-warning",
        INFO: "alert-info",
        LIGHT: "alert-light",
        DARK: "alert-dark"

    };
    static propTypes = {
        content: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
        type: PropTypes.oneOf(Object.values(Alert.types)),
        display: PropTypes.bool,
        closable: PropTypes.bool,
        onClose: PropTypes.bool,
        survivalTime: PropTypes.number,
        inClassName: PropTypes.string,
        outClassName: PropTypes.string
    };
    constructor(props){
        super(props);
        this.state = {
            //显示中(用于加载动画，先等待浏览器渲染完成，此时是隐藏状态，然后在改变style完成transition动画)
            showing: this.props.display,
            //是否隐藏(基于动画)
            hidden: !this.props.display,
            //是否显示
            display: this.props.display,
        };
    }
    //装载完成事件
    componentDidMount(){
        //加载动画
        CommonUtils.waitBrowserRender(this.container);
        this.setState(Object.assign({}, this.state, {showing: false}));
        if(typeof this.props.survivalTime === 'number'){
            setTimeout(()=>{
                this.hidden();
            }, this.props.survivalTime)
        }
    }
    //隐藏
    hidden(){
        this.setState(Object.assign({}, this.state, {hidden: true}));
    }
    //动画结束处理
    animationEndHandler(){
        if(this.state.hidden){
            this.setState(Object.assign({}, this.state, {display: false}));
            if(this.props.onClose instanceof Function)
                this.props.onClose();
        }
    }
    render(){
        let inAnimate = this.props.inAnimate || "fadeInRight";
        let outAnimate = this.props.outAnimate || "fadeOutRight";
        let type = this.props.type || Alert.types.INFO;
        return (
            <div
                ref={element=>this.container = element}
                className={"alert " + type + " animated " + ((this.state.showing || this.state.hidden)?outAnimate:inAnimate)}
                onAnimationEnd={this.animationEndHandler.bind(this)}
                style={Object.assign({display: ((this.state.display)?"block":"none")}, this.props.style)}
                role="alert">
                {this.props.children || this.props.content}
                {this.props.closable &&
                <button type="button" className="close" onClick={this.hidden.bind(this)}>
                    <span aria-hidden="true">&times;</span>
                </button>
                }
            </div>
        )
    }
}
Object.freeze(Alert.types);
